#ifndef __M_CONSUMER_H__
#define __M_CONSUMER_H__
/**
 * @file consumer.hpp
 * @brief 消息队列消费者管理模块
 * 
 * 本模块实现消费者的创建、删除、选择及生命周期管理功能。
 * 包含三个核心组件：
 * 1. Consumer - 消费者数据结构定义
 * 2. QueueConsumer - 单个队列的消费者管理
 * 3. ConsumerManager - 全局消费者管理器
 */

#include "../common/logger.hpp"
#include "../common/helper.hpp"
#include "../common/msg.pb.h"
#include <iostream>
#include <unordered_map>
#include <mutex>
#include <memory>
#include <vector>
#include <functional>

namespace bitmq 
{
    /// 消费者回调函数类型定义
    using ConsumerCallback = std::function<void(const std::string, const BasicProperties *bp, const std::string)>;
    
    /**
     * @struct Consumer
     * @brief 消费者数据结构
     * 
     * 表示一个消息消费者实体，包含消费者标识、订阅队列信息、确认模式和处理回调。
     */
    struct Consumer 
    {
        using ptr = std::shared_ptr<Consumer>; ///< 智能指针别名
        
        std::string tag;    ///< 消费者唯一标识符
        std::string qname;  ///< 消费者订阅的队列名称
        bool auto_ack;      ///< 自动消息确认标志（true=自动确认）
        ConsumerCallback callback; ///< 消息处理回调函数

        /// 默认构造函数（调试用）
        Consumer()
        {
            DLOG("new Consumer: %p", this);
        }
        
        /**
         * @brief 带参构造函数
         * @param ctag 消费者标识
         * @param queue_name 队列名称
         * @param ack_flag 自动确认标志
         * @param cb 消息处理回调
         */
        Consumer(const std::string &ctag, const std::string &queue_name,  bool ack_flag, const ConsumerCallback &cb):
            tag(ctag), qname(queue_name), auto_ack(ack_flag), callback(std::move(cb)) {
            DLOG("new Consumer: %p", this);
        }
        
        /// 析构函数（调试用）
        ~Consumer() 
        {
            DLOG("del Consumer: %p", this);
        }
    };

    /**
     * @class QueueConsumer
     * @brief 队列级消费者管理器
     * 
     * 管理单个队列的所有消费者，提供消费者管理及轮询选择功能。
     * 采用线程安全设计，支持多线程环境下的消费者操作。
     */
    class QueueConsumer 
    {
        public:
            using ptr = std::shared_ptr<QueueConsumer>; ///< 智能指针别名
            
            /**
             * @brief 构造函数
             * @param qname 管理的队列名称
             */
            explicit QueueConsumer(const std::string &qname) 
                : _qname(qname), _rr_seq(0) {}
            
            /**
             * @brief 创建新消费者
             * @param ctag 消费者标识
             * @param queue_name 队列名称
             * @param ack_flag 自动确认标志
             * @param cb 消息处理回调
             * @return 成功返回Consumer智能指针，失败返回空指针
             * 
             * 注意：消费者标识(ctag)必须唯一，重复创建会失败
             */
            Consumer::ptr create(const std::string &ctag, const std::string &queue_name,  
                                bool ack_flag, const ConsumerCallback &cb) 
            {
                // 加锁保证线程安全
                std::unique_lock<std::mutex> lock(_mutex);
                
                // 检查消费者标识是否重复
                for (auto &consumer : _consumers) 
                {
                    if (consumer->tag == ctag) 
                    {
                        return Consumer::ptr();
                    }
                }
                
                // 创建新消费者
                auto consumer = std::make_shared<Consumer>(ctag, queue_name, ack_flag, cb);
                _consumers.push_back(consumer);
                return consumer;
            }
            
            /**
             * @brief 移除指定消费者
             * @param ctag 要移除的消费者标识
             */
            void remove(const std::string &ctag) 
            {
                std::unique_lock<std::mutex> lock(_mutex);
                for (auto it = _consumers.begin(); it != _consumers.end(); ++it) 
                {
                    if ((*it)->tag == ctag) 
                    {
                        _consumers.erase(it);
                        return;
                    }
                }
            }
            
            /**
             * @brief 轮询选择消费者
             * @return 被选中的消费者智能指针，无消费者时返回空指针
             * 
             * 采用轮询(Round-Robin)算法公平选择消费者处理消息
             */
            Consumer::ptr choose() 
            {
                std::unique_lock<std::mutex> lock(_mutex);
                if (_consumers.empty()) 
                {
                    return Consumer::ptr();
                }
                
                // 轮询算法实现
                int idx = _rr_seq % _consumers.size();
                _rr_seq++;
                return _consumers[idx];
            }
            
            /// 检查当前队列是否无消费者
            bool empty() 
            {
                std::unique_lock<std::mutex> lock(_mutex);
                return _consumers.empty();
            }
            
            /**
             * @brief 检查消费者是否存在
             * @param ctag 消费者标识
             * @return 存在返回true，否则false
             */
            bool exists(const std::string &ctag) 
            {
                std::unique_lock<std::mutex> lock(_mutex);
                for (auto &consumer : _consumers) 
                {
                    if (consumer->tag == ctag) 
                    {
                        return true;
                    }
                }
                return false;
            }
            
            /// 清除当前队列所有消费者
            void clear() 
            {
                std::unique_lock<std::mutex> lock(_mutex);
                _consumers.clear();
                _rr_seq = 0;
            }
            
        private:
            std::string _qname;                ///< 管理的队列名称
            std::mutex _mutex;                 ///< 线程安全互斥锁
            uint64_t _rr_seq = 0;              ///< 轮询选择序列号
            std::vector<Consumer::ptr> _consumers; ///< 消费者指针集合
    };

    /**
     * @class ConsumerManager
     * @brief 全局消费者管理器
     * 
     * 管理系统中所有队列的消费者，提供跨队列的消费者操作接口。
     * 采用双层管理结构：队列名->QueueConsumer实例
     */
    class ConsumerManager 
    {
        public:
            using ptr = std::shared_ptr<ConsumerManager>; ///< 智能指针别名
            
            /// 默认构造函数
            ConsumerManager() = default;
            
            /**
             * @brief 初始化队列消费者管理
             * @param qname 队列名称
             * 
             * 为指定队列创建QueueConsumer管理实例
             */
            void initQueueConsumer(const std::string &qname) 
            {
                std::unique_lock<std::mutex> lock(_mutex);
                // 防止重复初始化
                if (_qconsumers.find(qname) != _qconsumers.end()) 
                {
                    return;
                }
                _qconsumers.emplace(qname, std::make_shared<QueueConsumer>(qname));
            }
            
            /**
             * @brief 销毁队列消费者管理
             * @param qname 队列名称
             */
            void destroyQueueConsumer(const std::string &qname) 
            {
                std::unique_lock<std::mutex> lock(_mutex);
                _qconsumers.erase(qname);
            }
            
            /**
             * @brief 创建新消费者
             * @param ctag 消费者标识
             * @param queue_name 队列名称
             * @param ack_flag 自动确认标志
             * @param cb 消息处理回调
             * @return 成功返回Consumer智能指针，失败返回空指针
             */
            Consumer::ptr create(const std::string &ctag, const std::string &queue_name,  
                                bool ack_flag, const ConsumerCallback &cb) 
            {
                QueueConsumer::ptr qcp = getQueueConsumer(queue_name);
                if (!qcp) return Consumer::ptr();
                return qcp->create(ctag, queue_name, ack_flag, cb);
            }
            
            /**
             * @brief 移除指定消费者
             * @param ctag 消费者标识
             * @param queue_name 队列名称
             */
            void remove(const std::string &ctag, const std::string &queue_name) 
            {
                if (QueueConsumer::ptr qcp = getQueueConsumer(queue_name)) {
                    qcp->remove(ctag);
                }
            }
            
            /**
             * @brief 选择消费者处理消息
             * @param queue_name 队列名称
             * @return 被选中的消费者智能指针
             */
            Consumer::ptr choose(const std::string &queue_name) 
            {
                if (QueueConsumer::ptr qcp = getQueueConsumer(queue_name)) {
                    return qcp->choose();
                }
                return Consumer::ptr();
            }
            
            /**
             * @brief 检查队列是否无消费者
             * @param queue_name 队列名称
             * @return 无消费者返回true，否则false
             */
            bool empty(const std::string &queue_name) 
            {
                if (QueueConsumer::ptr qcp = getQueueConsumer(queue_name)) {
                    return qcp->empty();
                }
                return true; // 视为空队列
            }
            
            /**
             * @brief 检查消费者是否存在
             * @param ctag 消费者标识
             * @param queue_name 队列名称
             * @return 存在返回true，否则false
             */
            bool exists(const std::string &ctag, const std::string &queue_name) 
            {
                if (QueueConsumer::ptr qcp = getQueueConsumer(queue_name)) {
                    return qcp->exists(ctag);
                }
                return false;
            }
            
            /// 清除所有队列的消费者
            void clear() 
            {
                std::unique_lock<std::mutex> lock(_mutex);
                _qconsumers.clear();
            }
            
        private:
            /**
             * @brief 获取队列消费者管理器
             * @param queue_name 队列名称
             * @return QueueConsumer智能指针，不存在时返回空指针
             */
            QueueConsumer::ptr getQueueConsumer(const std::string &queue_name) 
            {
                std::unique_lock<std::mutex> lock(_mutex);
                auto it = _qconsumers.find(queue_name);
                if (it == _qconsumers.end()) 
                {
                    DLOG("QueueConsumer not found for: %s", queue_name.c_str());
                    return nullptr;
                }
                return it->second;
            }
            
        private:
            std::mutex _mutex; ///< 全局互斥锁
            /// 队列消费者管理映射表 <队列名, QueueConsumer实例>
            std::unordered_map<std::string, QueueConsumer::ptr> _qconsumers;
    };
}

#endif